﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.IO;
using Microsoft.MediaCenter.UI;
using System.Diagnostics;
using MyVideoViewerLibrary;
//using Toub.MediaCenter.Dvrms.Metadata;

namespace MyVideoViewerMCPlugin
{
    public class SeriesGallery : GalleryPage
    {
        private TVSeries currentSeries;
        public TVSeries CurrentSeries
        {
            get { return currentSeries; }
            set
            {
                if (currentSeries != value)
                {
                    currentSeries = value;
                    FirePropertyChanged("CurrentSeries");
                }
            }
        }

        private int temp = 0;

        List<TVSeries> series = new List<TVSeries>();

        public SeriesGallery(List<Series> seriesList)
        {
            PropertyChanged += new PropertyChangedEventHandler(SeriesGallery_PropertyChanged);
            ShowChangeItemSize = true;
            ItemSize = (GalleryItemSize)Enum.Parse(typeof(GalleryItemSize),MySettings.Default.SeriesItemSize , true);
            Description = "TV Series";
            foreach (Series xseries in seriesList)
            {
                series.Add(new TVSeries(xseries));
            }
            
            VirtualList galleryList = new VirtualList(this, null);
            galleryList.EnableSlowDataRequests = true;
            galleryList.RequestSlowDataHandler = new RequestSlowDataHandler(CompleteGalleryItem);
            Content = galleryList;

            CreateGalleryFilters();
        }

        void SeriesGallery_PropertyChanged(IPropertyObject sender, string property)
        {
            if (property == "ItemSize")
            {
                MySettings.Default.SeriesItemSize = ItemSize.ToString();
                MySettings.Default.Save();
            }
        }

        private void CreateGalleryFilters()
        {
            //
            // Put together a list of filters on the content.
            //

            ArrayListDataSet list = new ArrayListDataSet(this);
            list.Add(new Filter(this, "Series", (int)FilterType.Title));
            list.Add(new Filter(this, "Rating", (int)FilterType.Rating));
            list.Add(new Filter(this, "TV Rating", (int)FilterType.MPAARating));
            list.Add(new Filter(this, "Genre", (int)FilterType.Genre));
            list.Add(new Filter(this, "Runtime", (int)FilterType.Runtime));
            list.Add(new Filter(this, "Day Airs", (int)FilterType.DayAirs));
            list.Add(new Filter(this, "Network", (int)FilterType.Network));
            list.Add(new Filter(this, "First Aired Date", (int)FilterType.ReleaseDate));
            

            // Create the unfiltered "All" filter
            //ModelItem filter = new Filter(this, Resources.GroupBy_Title, 0);
            Choice filters = new Choice(this, null, list);
            filters.Chosen = (ModelItem)list[0];

            ActiveFilterChanged += delegate(object sender, EventArgs e)
            {
                SeriesGallery galleryPage = (SeriesGallery)sender;
                Filter activeFilter = (Filter)galleryPage.Filters.Chosen;
                FilterContent(galleryPage, activeFilter.FilterId);
            };
            Filters = filters;

            //foreach (TVSeries s in series)
            //    this.Content.Add(CreateGalleryItem(s, "", false));
        }

        private void FilterContent(SeriesGallery page, int filterId)
        {
            Content.Clear();
            FilterType filterType = (FilterType)filterId;
            bool first = true;
            switch (filterType)
            {
                case FilterType.Rating:
                    
                    var ratings = series.Where(s=>s.Series.Rating.HasValue).OrderByDescending(s => s.Series.Rating).ThenBy(s => s.Series.SortName).GroupBy(s => s.Series.Rating);
                    foreach (var rating in ratings)
                    {
                        first = true;
                        foreach (var s in rating)
                        {
                            page.Content.Add(CreateGalleryItem(s, s.Series.Rating.Value.ToString(), first));
                            first = false;
                        }
                    }
                    first = true;
                    foreach (TVSeries s in series.Where(s => !s.Series.Rating.HasValue).OrderBy(s => s.Series.SortName))
                    {
                        page.Content.Add(CreateGalleryItem(s, "None", first));
                        first = false;
                    }
                    break;
                case FilterType.MPAARating:
                    foreach (TVSeries s in series.Where(s => s.Series.TVContentRating == null).OrderBy(s => s.Series.SortName))
                    {
                        page.Content.Add(CreateGalleryItem(s, "", false));
                    }

                    var tvratings = series.Where(s=>s.Series.TVContentRating != null).OrderBy(s => s.Series.TVContentRating.Description).ThenBy(s => s.Series.SortName).GroupBy(s => s.Series.TVContentRating.Description);
                    foreach (var tvrating in tvratings)
                    {
                        first = true;
                        foreach (var s in tvrating)
                        {
                            page.Content.Add(CreateGalleryItem(s, s.Series.TVContentRating != null ? s.Series.TVContentRating.Description : "", first));
                            first = false;
                        }
                    }
                    break;
                case FilterType.Genre:
                    var genres = series.OrderBy(s => s.GenresToString).ThenBy(s => s.Series.SortName).GroupBy(s => s.GenresToString);
                    foreach (var genre in genres)
                    {
                        first = true;
                        foreach (var s in genre)
                        {
                            page.Content.Add(CreateGalleryItem(s, s.GenresToString, first));
                            first = false;
                        }
                    }
                    break;
                case FilterType.ReleaseDate:
                    foreach (TVSeries s in series.Where(s => !s.Series.FirstAired.HasValue).OrderBy(s => s.Series.SortName))
                    {
                        page.Content.Add(CreateGalleryItem(s, "", false));
                    }

                    var aired = series.Where(s => s.Series.FirstAired.HasValue).OrderBy(s => s.Series.FirstAired.Value).ThenBy(s => s.Series.SortName).GroupBy(s => s.Series.FirstAired.Value);
                    foreach (var air in aired)
                    {
                        first = true;
                        foreach (var s in air)
                        {
                            page.Content.Add(CreateGalleryItem(s, s.Series.FirstAired.Value.ToShortDateString(), first));
                            first = false;
                        }
                    }
                    break;
                case FilterType.Runtime:
                    foreach (TVSeries s in series.Where(s => !s.Series.Runtime.HasValue).OrderBy(s => s.Series.SortName))
                    {
                        page.Content.Add(CreateGalleryItem(s, "", false));
                    }

                    var runtimes = series.Where(s => s.Series.Runtime.HasValue).OrderBy(s => s.Series.Runtime).ThenBy(s => s.Series.SortName).GroupBy(s => s.Series.Runtime.Value);
                    foreach (var runtime in runtimes)
                    {
                        first = true;
                        foreach (var s in runtime)
                        {
                            page.Content.Add(CreateGalleryItem(s, s.Series.Runtime.Value.ToString(), first));
                            first = false;
                        }
                    }
                    break;
                case FilterType.Network:
                    foreach (TVSeries s in series.Where(s => s.Series.Network == null).OrderBy(s => s.Series.SortName))
                    {
                        page.Content.Add(CreateGalleryItem(s, "", false));
                    }

                    var networks = series.Where(s => s.Series.Network != null).OrderBy(s => s.Series.Network.Name).ThenBy(s => s.Series.SortName).GroupBy(s => s.Series.Network.Name);
                    foreach (var network in networks)
                    {
                        first = true;
                        foreach (var s in network)
                        {
                            page.Content.Add(CreateGalleryItem(s, s.Series.Network.Name, first));
                            first = false;
                        }
                    }
                    break;
                case FilterType.DayAirs:

                    var airDays = series.OrderBy(s => s.Series.AirsDayOfWeek).ThenBy(s => s.Series.SortName).GroupBy(s => s.Series.AirsDayOfWeek);
                    foreach (var airDay in airDays)
                    {
                        first = true;
                        foreach (var s in airDay)
                        {
                            page.Content.Add(CreateGalleryItem(s, s.Series.AirsDayOfWeek, first));
                            first = false;
                        }
                    }
                    break;
                default:
                    foreach (TVSeries s in series)
                        this.Content.Add(CreateGalleryItem(s, "", false));
                    break;
            }
        }

        private ThumbnailCommand CreateGalleryItem(TVSeries seriesData, string description, bool isHeading)
        {
            ThumbnailCommand item = new ThumbnailCommand(this);
            item.Description = seriesData.Series.SeriesName;
            item.Data = seriesData;
            item.ShowHeading = isHeading;

            item.Metadata = description;

            item.Invoked += delegate(object sender, EventArgs args)
            {
                ThumbnailCommand galleryItem = (ThumbnailCommand)sender;
                Application.Current.GoToGalleryPage(new SeasonGallery(((TVSeries)galleryItem.Data).Series));
            };

            item.OnFocus += delegate(object sender, EventArgs args)
            {
                ThumbnailCommand galleryItem = (ThumbnailCommand)sender;

                SeriesGallery page = (SeriesGallery)galleryItem.Owner;
                page.CurrentSeries = (TVSeries)galleryItem.Data;
            };

            return item;
        }

        public override int JumpTo(string searchText)
        {
            searchText = searchText.ToLower();
            List<TVSeries> temp = null;
            do
            {

                temp = (from m in series
                        where m.Series.SortName.ToLower().StartsWith(searchText)
                        select m).ToList();
                if (searchText.Length > 0)
                    searchText = searchText.Substring(0, searchText.Length - 1);
            } while (temp.Count == 0 && searchText.Length > 0);

            if (temp.Count > 0)
            {
                int i = series.IndexOf(temp.First());
                return i;
            }
            return -1;
        }

        #region slowdatahandlers
        /// <summary>
        /// Finishes any slow data for a gallery item.
        /// </summary>
        protected void CompleteGalleryItem(VirtualList list, int index)
        {
            ThumbnailCommand item = (ThumbnailCommand)list[index];
            CompleteGalleryItem(item, (TVSeries)item.Data);
        }

        /// <summary>
        /// Finishes any slow data for a gallery item.
        /// </summary>
        protected void CompleteGalleryItem(ThumbnailCommand item, TVSeries seriesData)
        {
            string imageName = "file://" + seriesData.Series.FolderImage;
            item.Image = LoadImage(imageName);
        }
        #endregion

        //void AddRecordedToSeries(string filePath)
        //{
        //    using (DvrmsMetadataEditor editor = new DvrmsMetadataEditor(filePath))
        //    {
        //        IDictionary meta = editor.GetAttributes();

        //        string seriesTitle = ((MetadataItem)meta[MetadataEditor.Title]).Value.ToString();

        //        Series rSeries = series.FirstOrDefault(s => s.Name == seriesTitle && s.IsRecording == true);
        //        if (rSeries == null)
        //        {
        //            rSeries = new Series();
        //            rSeries.Name = seriesTitle;
        //            rSeries.IsRecording = true;
        //            //rSeries.FolderImage = 

        //            rSeries.SortName = rSeries.Name;
        //            if (rSeries.SortName.ToLower().StartsWith("the "))
        //                rSeries.SortName = rSeries.SortName.Substring(4) + ", The";

        //            series.Add(rSeries);

        //            Season season = new Season();
        //            season.Series = rSeries;
        //            rSeries.Seasons = new List<Season>() { season };

        //            season.Episodes = new List<Episode>();
        //        }

        //        Season rSeason = rSeries.Seasons.First();

        //        Episode rEpisode = new Episode();
        //        rEpisode.Name = ((MetadataItem)meta[MetadataEditor.Subtitle]).Value.ToString();
        //        rEpisode.Overview = ((MetadataItem)meta[MetadataEditor.SubtitleDescription]).Value.ToString();
        //        try
        //        {
        //            rEpisode.DateAdded = DateTime.Parse(((MetadataItem)meta["WM/MediaOriginalBroadcastDateTime"]).Value.ToString());
        //        }
        //        catch 
        //        {
        //            rEpisode.DateAdded = File.GetLastWriteTime(filePath);
        //        }

        //        rEpisode.MediaFile = new MediaFile() { FileName = Path.GetFileName(filePath), Path = filePath, Played = MyMoviesBrowserBusiness.CheckWatched(filePath) };

        //        rSeason.Episodes.Add(rEpisode);
        //    }
        //}
    }
}
